/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 * <p>
 * https://www.renren.io
 * <p>
 * 版权所有，侵权必究！
 */

package org.example.exception;



import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.example.common.JsonResult;
import org.example.common.aspect.FieldErrorWrapper;
import org.example.service.utils.CodeConst;
import org.example.service.utils.ErrConst;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.nio.file.AccessDeniedException;
import java.util.stream.Collectors;

import static org.springframework.http.HttpStatus.OK;

/**
 * 异常处理器
 *
 * @author sym
 */
@RestControllerAdvice
@Slf4j
public class BIzExceptionHandler {

    /**
     * 处理自定义异常
     */
    @ExceptionHandler(BizException.class)
    public JsonResult<Object> handleRRException(BizException e) {
        return JsonResult.error(e.getMsg(), null, CodeConst.E_KS);
    }

    /**
     * 处理自定义设备异常
     */
    @ExceptionHandler(DeviceException.class)
    public JsonResult<Object> handleDeviceException(DeviceException e) {
        return JsonResult.error(e.getMsg(), null, CodeConst.E_KS);
    }

    /**
     * 处理参数转化异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public JsonResult<Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.info(e.getMessage(), e);
        return JsonResult.error("参数校验失败！",
                e.getBindingResult().getAllErrors()
                        .stream().map(objectError -> objectError.getDefaultMessage())
                        .collect(Collectors.toList()),
                Strings.EMPTY);
    }

    @ExceptionHandler(EmptyResultDataAccessException.class)
    public JsonResult<Object> handleEmptyResultDataAccessException(EmptyResultDataAccessException e) {
        log.error(e.getMessage(), e);
        return JsonResult.error("记录不存在或已被删除！", e.getMessage(), Strings.EMPTY);
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public JsonResult<Object> handleAuthorizationException(IllegalArgumentException e) {
        log.error(e.getMessage(), e);
        return JsonResult.error("参数非法！", e.getMessage(), Strings.EMPTY);
    }

    @ExceptionHandler(Exception.class)
    public JsonResult<Object> handleException(Exception e) {
        log.error(e.getMessage(), e);
        return JsonResult.error("未知异常！", e.getMessage(), Strings.EMPTY);
    }

    /**
     * @param e
     * @return
     * @description 权限异常处理
     * @author tql
     * @date 22-10-11
     */
    @ExceptionHandler(AccessDeniedException.class)
    public JsonResult<Object> handleAccessDeniedException(AccessDeniedException e) {
        return JsonResult.error("权限异常！", e.getMessage(), ErrConst.E401);
    }

    /**
     * 处理异常
     *
     * @param e 异常参数
     * @return json结果
     */
    @ExceptionHandler(ValidationFailedException.class)
    @ResponseBody
    @ResponseStatus(OK)
    public JsonResult<FieldErrorWrapper> validationFailed(ValidationFailedException e) {
        log.trace("ValidationFailedException Found:" + e);
        return JsonResult.error("Validation Failed", e.getFieldErrorWrapper(), ErrConst.E01);
    }

    /**
     * 新参数校验异常处理，V1.2版本开始使用
     *
     * @param e
     * @return
     */
    @ExceptionHandler(NewValidationFailedException.class)
    @ResponseBody
    @ResponseStatus(OK)
    public JsonResult<FieldErrorWrapper> newValidationFailed(NewValidationFailedException e) {
        log.trace("NewValidationFailedException Found:" + e);
        return JsonResult.error("Validation Failed", e.getFieldErrorWrapper(), ErrConst.E01);
    }
}
